﻿using AutoMapper;
using System;
using System.Collections;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace CustomCommons
{
    /// <summary>
    /// 封装全局类型映射-扩展对象
    /// </summary>
    public static class AutoMapperExt
    {
        /// <summary>
        /// 扩展方法
        /// </summary>
        /// <param name="abc"></param>
        /// <returns></returns>
        public static string XYZ(this string abc)
        {
            //写自己的业务逻辑
            return abc + "---扩展方法：XYZ";
        }

        public static int aaa(this int abc)
        {
            //写自己的业务逻辑
            return abc + 100;
        }
        #region 解析
        //new MapperConfiguration() 创建一个新的 AutoMapper 配置实例
        //这个配置对象定义了如何在不同类型之间进行映射
        //2. 配置映射规则
        //cfg => cfg.CreateMap(obj.GetType(), typeof(T)) 是一个 Lambda 表达式
        //cfg 是配置构建器参数
        //CreateMap() 方法建立从源类型到目标类型的映射关系
        //3. 动态类型映射
        //obj.GetType() 获取源对象的实际运行时类型
        //typeof(T) 获取目标泛型类型 T 的类型信息
        //这样可以在运行时动态确定映射的源类型和目标类型
        #endregion 
        #region 案例
        //var user = new User { Name = "张三", Age = 25 };
        //var userDto = user.MapTo<UserDto>();
        //var config = new MapperConfiguration(cfg => cfg.CreateMap(typeof(User), typeof(UserDto)));
        #endregion
        /// <summary>
        ///  类型映射
        /// </summary>
        public static T MapTo<T>(this object obj)
        {
            if (obj == null) return default(T);

            var config = new MapperConfiguration(cfg => cfg.CreateMap(obj.GetType(), typeof(T)));
            var mapper = config.CreateMapper();
            return mapper.Map<T>(obj);
        }
        /// <summary>
        /// 集合列表类型映射
        /// </summary>
        public static List<TDestination> MapToList<TDestination>(this IEnumerable source)
        {
            Type sourceType = source.GetType().GetGenericArguments()[0];  //获取枚举的成员类型
            var config = new MapperConfiguration(cfg => cfg.CreateMap(sourceType, typeof(TDestination)));
            var mapper = config.CreateMapper();
            return mapper.Map<List<TDestination>>(source);
        }

        /// <summary>
        /// 集合列表类型映射
        /// </summary>
        public static List<TDestination> MapToList<TSource, TDestination>(this IEnumerable<TSource> source)
        {
            var config = new MapperConfiguration(cfg => cfg.CreateMap(typeof(TSource), typeof(TDestination)));
            var mapper = config.CreateMapper();

            return mapper.Map<List<TDestination>>(source);
        }

        /// <summary>
        /// 类型映射
        /// </summary>
        public static TDestination MapTo<TSource, TDestination>(this TSource source, TDestination destination)
            where TSource : class
            where TDestination : class
        {
            if (source == null) return destination;

            var config = new MapperConfiguration(cfg => cfg.CreateMap(typeof(TSource), typeof(TDestination)));
            var mapper = config.CreateMapper();
            return mapper.Map<TDestination>(source);
        }

    }
}
